package com.slyak.spring.jpa;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.xml.DefaultDocumentLoader;
import org.springframework.beans.factory.xml.DocumentLoader;
import org.springframework.beans.factory.xml.ResourceEntityResolver;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.xml.DomUtils;
import org.springframework.util.xml.SimpleSaxErrorHandler;
import org.springframework.util.xml.XmlValidationModeDetector;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;

/**
 * XML模板解析器，只解析后缀名为.xml的文件
 *
 * @author stormning on 2016/12/17.
 * wangjie modified on 2019/9/17 .
 */
public class XmlNamedTemplateResolver implements NamedTemplateResolver {
    protected final Log logger = LogFactory.getLog(getClass());

    private static final String SUFFIX = ".xml";

    private DocumentLoader documentLoader = new DefaultDocumentLoader();

    private ErrorHandler errorHandler = new SimpleSaxErrorHandler(logger);

    private ResourceLoader resourceLoader = new DefaultResourceLoader();

    private EntityResolver entityResolver = new ResourceEntityResolver(resourceLoader);

    @Override
    public Map<String, String> doInTemplateResource(Resource resource) {
        Map<String, String> sqlNamedMap = new HashMap<>();
        try {
            InputSource inputSource = new InputSource(resource.getInputStream());
            inputSource.setEncoding(StandardCharsets.UTF_8.name());
            Document doc = documentLoader.loadDocument(inputSource, entityResolver, errorHandler,
                    XmlValidationModeDetector.VALIDATION_XSD, false);
            final List<Element> sqes = DomUtils.getChildElementsByTagName(doc.getDocumentElement(), "sql");

            for (Element sqle : sqes) {
                sqlNamedMap.put(sqle.getAttribute("name"), sqle.getTextContent());
            }
        } catch (Exception e) {
            logger.error("读取XML文件" + resource.getFilename() + "出错");
        }
        return sqlNamedMap;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * spring.data.jpa.repository.support.freemarker.NamedTemplateResolver#getSuffix
     * ()
     */
    @Override
    public String getSuffix() {
        return SUFFIX;
    }
}
